/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package proxy;

import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.impl.client.DefaultHttpClient;

/**
 *
 * @author Hue
 */
public class OpenURL  extends HttpServlet {
    //private final String COOKIES_IN_SESSION = "COOKIES_IN_SESSION";
    public static String CONFIG_FILE;
    public static String REMOTE_SERVER;
    public static int WAIT = 0;
    public static Properties clients;

    @Override
    public void doGet(final HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException {
        if(!allow(request) || REMOTE_SERVER == null || REMOTE_SERVER.isEmpty()) {
            return;
        }
        DefaultHttpClient httpclient = getHttpClient(request);
        try {
            String requestURI = REMOTE_SERVER + request.getRequestURI();
            if(request.getQueryString() != null) {
                 requestURI += "?" + request.getQueryString();
            }
            System.out.println("doGet: " + requestURI);
            HttpGet httpget = new HttpGet(requestURI.toString());
            setHeaders(request, httpget);

            HttpResponse httpResponse = httpclient.execute(httpget);
            //setResponseHeaders(request, response, httpResponse);
            HttpEntity entity = httpResponse.getEntity();
            if(entity != null) {
                entity.writeTo(response.getOutputStream());
            }
            else {
                System.out.println(":::" + httpResponse);
            }
        }
        catch (Exception ex) {
            System.out.println("doGet: " + ex);
        }
        finally {
            //System.out.println(httpclient.getCookieStore());
            //request.getSession().setAttribute(COOKIES_IN_SESSION, httpclient.getCookieStore());
            //httpclient.getConnectionManager().shutdown();
        }
    }
    
    @Override
    public void doPost(final HttpServletRequest request, final HttpServletResponse response) throws IOException, ServletException {
        if(!allow(request) || REMOTE_SERVER == null || REMOTE_SERVER.isEmpty()) {
            return;
        }
        DefaultHttpClient httpclient = getHttpClient(request);
        try {
            String requestURI = REMOTE_SERVER + request.getRequestURI();
            if(request.getQueryString() != null) {
                 requestURI += "?" + request.getQueryString();
            }
            System.out.println("doPost: " + requestURI);
            HttpPost httpPost = new HttpPost(requestURI);
            byte[] payload = readData(request.getInputStream());
            String strPayload = new String(payload);
            System.out.println("payload:" + strPayload);
            setHeaders(request, httpPost);
            httpPost.setEntity(new ByteArrayEntity(payload));
            HttpResponse httpResponse = httpclient.execute(httpPost);
            HttpEntity entity = httpResponse.getEntity();
            if(entity != null) {
                entity.writeTo(response.getOutputStream());
            }
            else {
                System.out.println(":::" + httpResponse);
            }
        }
        catch (Exception ex) {
            System.out.println("doPost: " + ex);
        }
        finally {
            //System.out.println(httpclient.getCookieStore());
            //request.getSession().setAttribute(COOKIES_IN_SESSION, httpclient.getCookieStore());
            //httpclient.getConnectionManager().shutdown();
        }
    }
    
    private void setHeaders(HttpServletRequest request, HttpRequestBase httpRequest) throws IOException {
        /*
        Enumeration e = request.getHeaderNames();
        while(e.hasMoreElements()) {
            String key = (String) e.nextElement();
            httpRequest.setHeader(key, request.getHeader(key));
        }
        */
        String referer = request.getHeader("Referer");
        //System.out.println("Referer:->: " + referer);
        httpRequest.setHeader("referer", referer);
        httpRequest.setHeader("content-type", request.getContentType());
    }
    
    private DefaultHttpClient getHttpClient(HttpServletRequest request) throws IOException {
        String DEFAULT_HTTP_CLIENT = "DEFAULT_HTTP_CLIENT_" + request.getRemoteAddr();
        DefaultHttpClient httpclient = (DefaultHttpClient) getServletContext().getAttribute(DEFAULT_HTTP_CLIENT);
        if(httpclient == null) {
            httpclient = new DefaultHttpClient();
            httpclient.getParams().setParameter("http.useragent", request.getHeader("User-Agent"));
            getServletContext().setAttribute(DEFAULT_HTTP_CLIENT, httpclient);
        }
        //httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
        //System.out.println("User-Agent::" + request.getHeader("User-Agent"));
        //CookieStore cookieStore = (CookieStore) request.getSession().getAttribute(COOKIES_IN_SESSION);
        //if(cookieStore != null) {
            //httpclient.setCookieStore(cookieStore);
        //}
        return httpclient;
    }
    
    protected String replace(final String _str, final String _strOld, final String _strNew) {
        if(_str == null || _strOld == null || _strNew == null || _str.indexOf(_strOld) == -1) {
            return _str;
        }
        StringBuffer sb = new StringBuffer(_str);
        int iIndex = 0;
        while((iIndex = sb.indexOf(_strOld,iIndex)) != -1) {
            sb = sb.replace(iIndex,iIndex+_strOld.length(),_strNew);
            iIndex += _strNew.length();
        }
        
        return sb.toString();
    }

    protected byte[] readData(final InputStream in) throws java.io.IOException {
        final ByteArrayOutputStream baOut = new ByteArrayOutputStream();
        int nByte;
        final byte[] buff = new byte[1024*1024];
        while((nByte = in.read(buff)) > 0) {
            baOut.write(buff,0, nByte);
        }
        final byte[] data = baOut.toByteArray();
        baOut.close();
        
        return data;
    }
    
    protected void writeFile(String filename, byte[] data) throws java.io.IOException {
        FileOutputStream out = new FileOutputStream(filename);
        out.write(data);
        out.close();
    }
    
    private boolean allow(HttpServletRequest request) {
        String clientIp = request.getRemoteAddr();
        if(clients == null || !clients.containsValue(clientIp)) {
            return false;
        }
        return true;
    }
}
